import { ref, computed, reactive } from 'vue'

/**
 * 角色变换属性
 */
export interface Transform {
  x: number
  y: number
  scaleX: number
  scaleY: number
  rotation: number
  skewX: number
  skewY: number
  anchorX: number
  anchorY: number
}

/**
 * 角色外观属性
 */
export interface Appearance {
  opacity: number
  visible: boolean
  blendMode: string
  filters: any[]
  tint: string
}

/**
 * 角色动画关键帧
 */
export interface Keyframe {
  frame: number
  transform: Partial<Transform>
  appearance: Partial<Appearance>
  easing?: string
}

/**
 * 角色资源信息
 */
export interface CharacterAsset {
  id: string
  type: 'image' | 'svg' | 'sprite'
  url: string
  width: number
  height: number
  frames?: number // 用于精灵动画
}

/**
 * 角色类
 */
export class Character {
  public readonly id: string
  public name = ref('')
  public asset = ref<CharacterAsset | null>(null)
  
  // 变换属性
  public transform = reactive<Transform>({
    x: 0,
    y: 0,
    scaleX: 1,
    scaleY: 1,
    rotation: 0,
    skewX: 0,
    skewY: 0,
    anchorX: 0.5,
    anchorY: 0.5
  })
  
  // 外观属性
  public appearance = reactive<Appearance>({
    opacity: 1,
    visible: true,
    blendMode: 'normal',
    filters: [],
    tint: '#ffffff'
  })
  
  // 动画关键帧
  public keyframes = ref<Keyframe[]>([])
  
  // 层级
  public zIndex = ref(0)
  
  // 是否被选中
  public selected = ref(false)
  
  // 是否被锁定
  public locked = ref(false)
  
  constructor(id: string, name: string = '') {
    this.id = id
    this.name.value = name || `Character_${id.slice(0, 8)}`
  }
  
  /**
   * 设置角色资源
   */
  public setAsset(asset: CharacterAsset): void {
    this.asset.value = asset
  }
  
  /**
   * 添加关键帧
   */
  public addKeyframe(frame: number, properties: Partial<Transform & Appearance>): void {
    const existingIndex = this.keyframes.value.findIndex(kf => kf.frame === frame)
    
    const keyframe: Keyframe = {
      frame,
      transform: {},
      appearance: {}
    }
    
    // 分离变换和外观属性
    Object.entries(properties).forEach(([key, value]) => {
      if (key in this.transform) {
        keyframe.transform[key as keyof Transform] = value
      } else if (key in this.appearance) {
        keyframe.appearance[key as keyof Appearance] = value
      }
    })
    
    if (existingIndex >= 0) {
      // 更新现有关键帧
      this.keyframes.value[existingIndex] = {
        ...this.keyframes.value[existingIndex],
        ...keyframe
      }
    } else {
      // 添加新关键帧
      this.keyframes.value.push(keyframe)
      this.keyframes.value.sort((a, b) => a.frame - b.frame)
    }
  }
  
  /**
   * 删除关键帧
   */
  public removeKeyframe(frame: number): boolean {
    const index = this.keyframes.value.findIndex(kf => kf.frame === frame)
    if (index >= 0) {
      this.keyframes.value.splice(index, 1)
      return true
    }
    return false
  }
  
  /**
   * 获取指定帧的插值属性
   */
  public getInterpolatedProperties(frame: number): Transform & Appearance {
    const keyframes = this.keyframes.value
    
    if (keyframes.length === 0) {
      return { ...this.transform, ...this.appearance }
    }
    
    // 找到当前帧前后的关键帧
    let prevKeyframe: Keyframe | null = null
    let nextKeyframe: Keyframe | null = null
    
    for (let i = 0; i < keyframes.length; i++) {
      if (keyframes[i].frame <= frame) {
        prevKeyframe = keyframes[i]
      }
      if (keyframes[i].frame > frame && !nextKeyframe) {
        nextKeyframe = keyframes[i]
        break
      }
    }
    
    // 如果没有前一个关键帧，使用默认值
    if (!prevKeyframe) {
      return { ...this.transform, ...this.appearance }
    }
    
    // 如果没有后一个关键帧，使用前一个关键帧的值
    if (!nextKeyframe) {
      return this.applyKeyframeProperties(prevKeyframe)
    }
    
    // 计算插值
    const t = (frame - prevKeyframe.frame) / (nextKeyframe.frame - prevKeyframe.frame)
    return this.interpolateKeyframes(prevKeyframe, nextKeyframe, t)
  }
  
  /**
   * 应用关键帧属性
   */
  private applyKeyframeProperties(keyframe: Keyframe): Transform & Appearance {
    const result = { ...this.transform, ...this.appearance }
    
    Object.assign(result, keyframe.transform)
    Object.assign(result, keyframe.appearance)
    
    return result
  }
  
  /**
   * 插值两个关键帧
   */
  private interpolateKeyframes(prev: Keyframe, next: Keyframe, t: number): Transform & Appearance {
    const result = { ...this.transform, ...this.appearance }
    
    // 插值变换属性
    Object.entries(prev.transform).forEach(([key, prevValue]) => {
      const nextValue = next.transform[key as keyof Transform]
      if (typeof prevValue === 'number' && typeof nextValue === 'number') {
        result[key as keyof Transform] = this.lerp(prevValue, nextValue, t)
      }
    })
    
    // 插值外观属性
    Object.entries(prev.appearance).forEach(([key, prevValue]) => {
      const nextValue = next.appearance[key as keyof Appearance]
      if (typeof prevValue === 'number' && typeof nextValue === 'number') {
        result[key as keyof Appearance] = this.lerp(prevValue, nextValue, t)
      } else if (key === 'visible') {
        // 布尔值在中点切换
        result.visible = t < 0.5 ? (prevValue as boolean) : (nextValue as boolean)
      }
    })
    
    return result
  }
  
  /**
   * 线性插值
   */
  private lerp(start: number, end: number, t: number): number {
    return start + (end - start) * t
  }
  
  /**
   * 更新角色在指定帧的属性
   */
  public updateAtFrame(frame: number): void {
    const properties = this.getInterpolatedProperties(frame)
    
    // 更新变换属性
    Object.assign(this.transform, {
      x: properties.x,
      y: properties.y,
      scaleX: properties.scaleX,
      scaleY: properties.scaleY,
      rotation: properties.rotation,
      skewX: properties.skewX,
      skewY: properties.skewY,
      anchorX: properties.anchorX,
      anchorY: properties.anchorY
    })
    
    // 更新外观属性
    Object.assign(this.appearance, {
      opacity: properties.opacity,
      visible: properties.visible,
      blendMode: properties.blendMode,
      tint: properties.tint
    })
  }
  
  /**
   * 克隆角色
   */
  public clone(newId: string): Character {
    const cloned = new Character(newId, `${this.name.value}_copy`)
    
    // 复制资源
    cloned.asset.value = this.asset.value
    
    // 复制变换属性
    Object.assign(cloned.transform, this.transform)
    
    // 复制外观属性
    Object.assign(cloned.appearance, this.appearance)
    
    // 复制关键帧
    cloned.keyframes.value = this.keyframes.value.map(kf => ({ ...kf }))
    
    // 复制其他属性
    cloned.zIndex.value = this.zIndex.value
    
    return cloned
  }
  
  /**
   * 导出角色数据
   */
  public export(): any {
    return {
      id: this.id,
      name: this.name.value,
      asset: this.asset.value,
      transform: { ...this.transform },
      appearance: { ...this.appearance },
      keyframes: this.keyframes.value.map(kf => ({ ...kf })),
      zIndex: this.zIndex.value,
      locked: this.locked.value
    }
  }
  
  /**
   * 从数据导入角色
   */
  public import(data: any): void {
    this.name.value = data.name || this.name.value
    this.asset.value = data.asset || null
    
    if (data.transform) {
      Object.assign(this.transform, data.transform)
    }
    
    if (data.appearance) {
      Object.assign(this.appearance, data.appearance)
    }
    
    if (data.keyframes) {
      this.keyframes.value = data.keyframes
    }
    
    this.zIndex.value = data.zIndex || 0
    this.locked.value = data.locked || false
  }
  
  /**
   * 计算属性：边界框
   */
  public get boundingBox() {
    return computed(() => {
      if (!this.asset.value) {
        return { x: 0, y: 0, width: 0, height: 0 }
      }
      
      const { width, height } = this.asset.value
      const { x, y, scaleX, scaleY, anchorX, anchorY } = this.transform
      
      const scaledWidth = width * Math.abs(scaleX)
      const scaledHeight = height * Math.abs(scaleY)
      
      return {
        x: x - scaledWidth * anchorX,
        y: y - scaledHeight * anchorY,
        width: scaledWidth,
        height: scaledHeight
      }
    })
  }
}
